/*
 *  EventLib
 *  qEventRegistry.h
 *
 *	Copyright (c) 2011, AVS
 *	All rights reserved.
 *
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	1.	Redistributions of source code must retain the above copyright
 *		notice, this list of conditions and the following disclaimer.
 *	2.	Redistributions in binary form must reproduce the above copyright
 *		notice, this list of conditions and the following disclaimer in the
 *		documentation and/or other materials provided with the distribution.
 *	3.	All advertising materials mentioning features or use of this software
 *		must display the following acknowledgement:
 *		This product includes software developed by the AVS.
 *	4.	Neither the name of the AVS nor the
 *		names of its contributors may be used to endorse or promote products
 *		derived from this software without specific prior written permission.
 *
 *	THIS SOFTWARE IS PROVIDED BY AVS ''AS IS'' AND ANY
 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL AVS BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _qEventRegistry_h
#define _qEventRegistry_h

#include <list>
#include <vector>

#include "EventLib.h"

#define REGISTER_LISTENER(REGISTRY, LISTENER, HANDLER, OBJ) \
REGISTRY->register_event<LISTENER, HANDLER>(OBJ);\
((qEventListener*)OBJ->getComp("event_listener"))->init(); 

#define REGISTER_HANDLER(HANDLER, OBJ, EXEC) \
((HANDLER *)OBJ->getComp("event_handler"))->set_exec(EXEC);

#define REGISTER_PAIR(REGISTRY, LISTENER, HANDLER, OBJ, EXEC) \
REGISTER_LISTENER(REGISTRY, LISTENER, HANDLER, OBJ); \
REGISTER_HANDLER(HANDLER, OBJ, EXEC);


class qEventRegistry
{
public:
	qEventRegistry();
	~qEventRegistry();
	
	template<typename L>
	qComponent *make_listerner();
	template<typename L, typename H>
	bool register_event(qComponent *comp);
	
	std::list<qEventListener*> &pGetListeners() { return this->listeners; }
	
	void push_event(qEvent evt);
	void process_events();
	
private:
	std::list<qEventListener*> listeners;
	std::vector<qEvent> events;
};

template<typename L>
qComponent *qEventRegistry::make_listerner()
{
	qEventListener *listener = new L();
	this->listeners.push_back(listener);
	return listener;
}

template<typename L, typename H>
bool qEventRegistry::register_event(qComponent *comp)
{
	comp->addComp("event_handler", new H());
	comp->addComp("event_listener", this->make_listerner<L>());
	return true;
}

#endif